package torres.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;

import torres.entity.Avatar;
import torres.map.Location;
import torres.map.Map;
import torres.map.World;

/**
 * @author Torres
 * Actually draws the 2D graphics for the game and everything
 * related to how the images get displayed.
 */
@SuppressWarnings("serial")
public class TwoDAreaViewPort extends AreaViewPort {
	private Map map = world.getCurrentMap();
	private JLayeredPane layerPane;
	private int imageWidth;
	private int imageHeight;
	
	/**
	 * Creates a new TwoDAreaViewPort with the default settings.
	 */
	public TwoDAreaViewPort() {
		this.setBackground(Color.BLACK);
		this.setPreferredSize(new Dimension(AREA_WIDTH, AREA_HEIGHT));
		layerPane = new JLayeredPane();
		layerPane.setPreferredSize(new Dimension(AREA_WIDTH, AREA_HEIGHT));
		imageWidth = 100;
		imageHeight = 100;
		this.add(layerPane, BorderLayout.WEST);
		layerPane.setFocusable(true);
		for(int i = 0; i < 25; ++i) {
			layerPane.add(new JLabel(), JLayeredPane.POPUP_LAYER);
			layerPane.add(new JLabel(), JLayeredPane.MODAL_LAYER);
			layerPane.add(new JLabel(), JLayeredPane.PALETTE_LAYER);
			layerPane.add(new JLabel(), JLayeredPane.DEFAULT_LAYER);
		}
		setVisible(true);
	}
	
	/* (non-Javadoc)
	 * @see torres.view.AreaViewPort#draw()
	 */
	@Override
	public void draw() {
		
		layerPane.requestFocus();
		map = World.getInstance().getCurrentMap();
		Avatar avatar = map.getAvatar();
		Location location = avatar.getLocation();
		int x = 0;
		int rowNum = 0;
		int colNum = 0;
		ImageLoader img;
		
		/*Components are stored from closest layer to farthest away layer and are in the order
		 * you stored them in if they are on the same layer.
		 * i & j are for (y,x) location on the map
		 * rowNum & colNum are for relative location on AreaViewPort grid
		 * x is for component number.
		 */
		
		/* Draws Top layer with entity */
		
		for (int i = location.getY()-2; i < location.getY() + 3; i++) {
			for(int j = location.getX() - 2; j < location.getX() + 3; j++) {
				
				JLabel item = (JLabel) layerPane.getComponent(x);
				item.setBounds(colNum*getImageWidth(),rowNum*getImageHeight(),getImageWidth(),getImageHeight());
				if(map.getTiles()[i][j].getEntity() != null) {
					img = new ImageLoader(map.getTiles()[i][j].getEntity().getImageName());
					item.setIcon(img.getImgIcon());
				}
				else
					item.setIcon(null);
				
				x++;
				colNum++;
			}
			rowNum++;
			colNum=0;
		}
		colNum=0;
		rowNum=0;
		
		/*Draws 2nd layer with Items*/
		
		for (int i = location.getY() - 2; i < location.getY() + 3; i++) {
			for(int j = location.getX() - 2; j < location.getX() + 3; j++) {
				
				JLabel item = (JLabel) layerPane.getComponent(x);
				item.setBounds(colNum*getImageWidth(),rowNum*getImageHeight(),getImageWidth(),getImageHeight());
				if(map.getTiles()[i][j].getItem() != null) {
					img = new ImageLoader(map.getTiles()[i][j].getItem().getImageName());
					item.setIcon(img.getImgIcon());
					//System.out.println("Row: " + i + "Col: " + j);
				}
				
				else
					item.setIcon(null);
				
				x++;
				colNum++;				
			}
			rowNum++;
			colNum=0;
		}
		colNum=0;
		rowNum=0;
		
		/* Draws bottom 2 layers with decals and terrain */
		
		x+=25;
		for (int i = location.getY() - 2; i < location.getY() + 3; i++) {
			for(int j = location.getX() - 2; j < location.getX() + 3; j++) {
				JLabel item = (JLabel) layerPane.getComponent(x);
				item.setBounds(colNum*getImageWidth(),rowNum*getImageHeight(),getImageWidth(),getImageHeight());
				
				//Check if out map tile being accessed is out of bounds, if so make it the image a mountain
				/*If we can ever change areaViewPort size, this may be needed
				if(i < 0 || j < 0 || (i > map.getTiles().length || j > map.getTiles()[i].length )) 
					img = new ImageLoader(ImageLoader.imagePath + Mountain.getInstance().getImageName());
				*/
				
				//Else check if it has a decal on it so we can do the image overlay
				JLabel decal = (JLabel) layerPane.getComponent(x-25);
				if(map.getTiles()[i][j].getImageName().contains("|")) {
					decal.setBounds(colNum*getImageWidth(),rowNum*getImageHeight(),getImageWidth(),getImageHeight());
					int index = map.getTiles()[i][j].getImageName().indexOf('|');
					img = new ImageLoader(map.getTiles()[i][j].getImageName().substring(0,index));
					ImageLoader decalImg = new ImageLoader(map.getTiles()[i][j].getImageName().substring(index+1));
					decal.setIcon(decalImg.getImgIcon());
				}
				
				//Else just treat it like a normal terrain
				
				else {
					img = new ImageLoader(map.getTiles()[i][j].getImageName());
					decal.setIcon(null);
				}
				
				//Set the bottom level terrain image
				
				item.setIcon(img.getImgIcon());
				x++;
				colNum++;
			}
			rowNum++;
			colNum=0;
		}
	}
	
	/* (non-Javadoc)
	 * @see torres.view.AreaViewPort#setCurrentMap(torres.map.Map)
	 */
	@Override
	public void setCurrentMap(Map map) {
		this.map = map;
	}

	/* (non-Javadoc)
	 * @see torres.view.AreaViewPort#getArea()
	 */
	@Override
	public JComponent getArea() {
		//layerPane.requestFocus();
		return layerPane;
	}

	/**
	 * Returns the current image width.
	 * @return The current image width.
	 */
	public int getImageWidth() {
		return imageWidth;
	}

	/**
	 * Sets the image width to the specified value.
	 * @param imageWidth The new value for the image width.
	 */
	public void setImageWidth(int imageWidth) {
		this.imageWidth = imageWidth;
	}

	/**
	 * Returns the current image height.
	 * @return The current image height.
	 */
	public int getImageHeight() {
		return imageHeight;
	}

	/**
	 * Sets the image height to the specified value.
	 * @param imageHeight The new value for the image height.
	 */
	public void setImageHeight(int imageHeight) {
		this.imageHeight = imageHeight;
	}
	
	/* (non-Javadoc)
	 * @see torres.view.AreaViewPort#getLayerPane()
	 */
	public JLayeredPane getLayerPane() {
		return layerPane;
	}

	/* (non-Javadoc)
	 * @see torres.view.AreaViewPort#isAscii()
	 */
	@Override
	public boolean isAscii() {
		return false;
	}

	/* (non-Javadoc)
	 * @see torres.view.AreaViewPort#isTwoD()
	 */
	@Override
	public boolean isTwoD() {
		return true;
	}	
}